-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove duplicate procedures from miden-lib
#1002
Conversation
787743f
to
b6267d9
Compare
This solution implements the whole new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! Looks good. I left a few comment inline, but basically, there are two properties I'd like to retain:
- Ideally, we won't need to add a new library to the list of libraries that we need to load into the executor and transaction kernel assembler.
- Also, we should try to avoid changing the public interface of the modules in
miden-lib
(would should be able to just re-export procedures from the modules in which they were previously defined).
We could have achieved both of these if we had vendored library support in the assembler, but without it, I think we may need to rely on adding the MASM file with common utilities to tx kernel and miden lib libraries manually at build time.
miden-lib/asm/miden/account.masm
Outdated
proc.type | ||
u32split swap drop push.ACCOUNT_TYPE_U32MASK u32and | ||
# => [acct_type] | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above.
miden-lib/src/utils_lib.rs
Outdated
#[derive(Clone)] | ||
pub struct UtilsLib(Library); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a brief doc-comment explaining what this library contain.
miden-tx/src/executor/mast_store.rs
Outdated
// load utils lib MAST forest | ||
let utils_lib_forest = UtilsLib::default().mast_forest().clone(); | ||
store.insert(utils_lib_forest); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I like that we now need to care about another library. Ideally, we'd just vendor the utils library into the miden
library at compile time, but unfortunately, Miden assembler does not yet support vendoring. So, maybe trying the approach with a single MASM file is worth it.
cc @plafer, @bitwalker for another use case for vendored library.
b6267d9
to
4454352
Compare
4454352
to
73fa206
Compare
Overall, I think this looks good, but as discussed offline, I wonder if we should take this as an opportunity to refactor things a bit more in the direction mention in #982 (comment). Basically, try to identify pure "utility" procedures and move them out into separate "util" modules. |
miden-lib/asm/utils.masm
Outdated
#! - acct_id_{hi,lo} are the first and second felt of an account id. | ||
#! - other_acct_id_{hi,lo} are the first and second felt of the other account id to compare against. | ||
#! - is_id_equal is a boolean indicating whether the account ids are equal. | ||
export.is_id_eq |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This procedure (and procedures above) could maybe go into account_id
module or something similar (e.g., account_id::are_equal
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I'm following. Do you mean to split utils
into several modules like account
, asset
and note
, as it was when it was a library? And I'm not sure that account_id
as a name for one of these modules will fit, is_id_eq
is the only procedure which is working with account IDs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm thinking of creating several modules that separate "stateful" and "stateless" procedures. I haven't looked through everything to know where it'd make sense, but for account ID there are at least several "stateless" procedures that can go into an account_id
module - e.g., is_id
, is_fungible_faucet
, is_non_fungible_faucet
, is_faucet
, is_updatable_account
, is_immutable_account
, validate_id
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see, so you meant not just splitting the existing utils
module, but combining it with the "pure utils" modules created from the corresponding kernel modules. Got it!
67352f0
to
21f1671
Compare
I think this might be ready now. I moved all pure procedures to one of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PhilippGackstatter Looks great!
The only think I'm wondering about is whether we need to reexport the utils procedures from the main files (like account_utils
procs from the account
) to leave the public interface unchanged, as Bobbin said here.
Honestly, I forgot about it after we decide to make a bigger refactoring, introducing the new *_utils
modules, since it looked as we need to change public interface anyway. But the issue with testing assembler reminded me about it (I had it previously): if we reexport utils procedures in the main modules, we don't need to add the utils
module manually to the testing assembler — its mast forest will be in the kernel library.
I'm not sure what's better: on the one hand, if we reexport all these procedures user won't need to think where to get the desired procedure — just call it from corresponding module. On the other hand, currently we have quite a lot procedures in kernel modules, so it could be better to separate utils from non-utils to make it easier and slightly less confusing to operate them. But if we decide to reexport all of them, it looks like we are loosing the initial idea of moving utils procedures to another module.
@bobbinth what do you think?
#[cfg(feature = "std")] | ||
let mut assembler = assembler; | ||
// We don't build the utils modules as a library in build.rs so we have to load it here | ||
// instead. This means it won't be included in no_std environments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it more efficient to create a new mutable value inside the feature block than just make the original one mutable?
Or, in other words, will it be less efficient just to make the assembler instance at line 362 mutable and remove these lines (370-373) moving the comment inside the feature block?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! Looks good. I left a few comments inline, the main one being about trying avoid the manipulations of the testing assembler.
There is also a slight different approach where we have common modules which we add into different libraries under different namespaces. A good example of this is the assets
module. If we have a module that is a combination of the current asset_utils
module and miden::assets
module, we could just add it to both libraries under different namespaces (miden:assets
and kernel::assets
).
We could do the same with account_utils
. I think most of the procedures there are actually about account ID. So, maybe we create a common module named account_id
and add it to the kernel and Miden library as kernel::account_id
and miden::account_id
respectively.
# HELPER PROCEDURES | ||
# ================================================================================================= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: seems like all procedures starting on line 273 are helper procedures. Should we move the separator there?
miden-lib/build.rs
Outdated
let utils_namespace = LibraryNamespace::new("utils").expect("invalid namespace"); | ||
let utils_path = Path::new(ASM_DIR).join(UTILS_DIR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One other way to do this is to set the namespace here to be kernel::utils
to make it specific to the kernel. We could also do the same for the miden
library but importing the same files under miden::utils
namespace.
/// This assembler also includes the `utils` namespace which contains the modules defined | ||
/// in the utils directory (only under feature `std`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we do what I suggested in the last comment, would we be able to avoid needing to manually import utils
here?
miden-lib/asm/utils/asset_utils.masm
Outdated
@@ -0,0 +1,193 @@ | |||
use.utils::account_utils |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This import may cause an issue with my suggestions form the last comments. But I wonder if we can get rid of it. There are 3 procedures in this module which rely on account_utils
and as far as I can tell, these procedures are not "shared". So, if we move them back into the kernel asset
module, we could get rid of this import.
I really like this idea. Not sure if you deliberately wrote But the assembler doesn't allow defining a single |
Yes, sorry - it should be one module.
For For |
Ah I see what you mean. I initially understood it as only union of Edit: Ah no,
Agreed. |
I tried combining these files:
into a single file Even if this would not be a problem like for Please correct me if I'm wrong, but I think even with library vendoring we'd have the same problem. The only difference with vendoring would be that if utils was a So unless I'm missing something, I would probably (in another PR) explore this idea of manually combining multiple modules as mentioned above. What I don't yet know how to solve nicely is to create a single module out of multiple files, if somehow possible with the help of For now in this PR, I would only reexport procedures from kernel and miden lib from utils procedures and keep the public interface the same. Any thoughts? |
Superseded by #1070. |
This PR moves the duplicate
masm
procedures to the newutils
library.Todo: move the
is_id_eq
procedure to theutils
module after #982 is merged.Closes: #836